Makefile模板以及多层Makefile编译(附源码) 您所在的位置:网站首页 makefile -f Makefile模板以及多层Makefile编译(附源码)

Makefile模板以及多层Makefile编译(附源码)

2024-07-06 00:16| 来源: 网络整理| 查看: 265

本文将介绍几个Makefile模板:编译可执行程序、编译静态库、编译动态库。以及简单地介绍在项目工程多目录下多层Makefile如何编译

关于Makefile的介绍,欢迎查阅之前发过的文章,认识Makefile以及基础知识 和 Linux库概念、静态库、动态库

1、前言

 现在很多IDE都集成了编译器,如Visual Studio等等,点击相关的编译按钮的一个操作即可完成编译、链接、生成目标文件。

 在Linux系统下,开发并编译程序一般用的gcc/g++编译器,如果是开发ARM架构环境下的Linux程序,还需用到arm-linux-gcc/arm-linux-g++交叉编译器。

 其实Linux下也可以实现“一键编译”功能,特别是在大工程项目下,此时需要借助Makefile,一个命令就完成编译、链接、生成目标文件就显得很有用处了。Makefile可以手动编写,也可以借助自动化构建工具(如scons、CMake、autotools等)生成。一般地一个通用的Makefile能够适合大部分Linux项目程序。

2、Makefile工程管理

 工程管理器,顾名思义,是指管理较多的文件 Make工程管理器也就是个“自动编译管理器”,这里的“自动”是指它能构根据文件时间戳自动发现更新过的文件而减少编译的工作量,同时,它通过读入Makefile文件文件的内容来执行大量的编译工作。  在一个makefile中通常包含如下内容:   需要由make工具创建的目标体(target),通常是目标文件或可执行文件;   要创建的目标体所依赖的文件(dependency_file);   创建每个目标体时需要运行的命令(command),这一行必须以制表符(tab键)开头。

makefile格式 target: dependency_files command #该行必须以tab键开头 3、Makefile模板 3.1 使用Makefile编译可执行文件 PROJECT_ROOT_PATH = /home/yimning/MakefileTemplate VERSION = 1.0.0 CC = gcc DEBUG = -DUSE_DEBUG CFLAGS = -Wall SOURCES = $(wildcard *.c) INCLUDES = -I../../include #LIB_NAMES =-lfun_a -lfun_so # 如果使用到相关库,可添加。若没有就注释该行。 LIB_NAMES = -lfoo -lbar # 比如我这里分别使用了静态库libfoo.a.1.0.0和libbar.so.1.0.0(已放到了/lib下) LIB_PATH = -L./lib #使用到库的路径,一般放于/lib或在/usr/lib目录下 OBJ = $(patsubst %.c, %.o, $(SOURCES)) TARGET = app #links $(TARGET):$(OBJ) @mkdir -p output $(CC) $(OBJ) $(LIB_PATH) $(LIB_NAMES) -o output/$(TARGET).$(VERSION) @rm -rf $(OBJ) #compile %.o: %.c $(CC) $(INCLUDES) $(DEBUG) -c $(CFLAGS) $ printf("foo use bar function---output:%d\n",add(33,66)); return x+1; }

测试例程的test/main.c

/* * @Author: Yimning [email protected] * @Date: 2022-07-02 10:05:07 */ #include #include "bar/bar.h" #include "foo/foo.h" int main(void) { printf("this is bar function---output:%d\n", add(44, 44)); // 88 printf("this is foo function---output:%d\n", foo(add(33, 66))); // 99 return 0; }

测试例程的test/Makefile

EXE_NAME = app DEBUG = -D_MACRO #宏定义 #PROJECT_ROOT_PATH = /home/yimning/MakefileTemplate #VERSION = 1.0.0 CC = gcc DEBUG =-DUSE_DEBUG CFLAGS =-Wall CCSRCS = $(wildcard *.c) #获取所有的.c文件 CCOBJS = $(patsubst %.c,%.o, $(CCSRCS)) #符合模式[%.c]的单词替换成[%.o] 即将.c文件转为.o文件 INCPATH = -I../include -I$(PROJECT_ROOT_PATH)/include #头文件路径 LDFLAGS = -L$(PROJECT_ROOT_PATH)/lib #库文件路径 LIB_NAMES = $(LIB_SO_OBJS) $(LIBS_A_OBJS) #链接库文件名字 # 获取静态库名字 LIBS_A = $(wildcard $(PROJECT_ROOT_PATH)/lib/*.a) # 获取该目录下动态库(*.a)的路径名 LIBS_A_NOTDIR = $(notdir $(LIBS_A)) # 去掉路路径,只留下文件名为libxxx.a LIBS_A_NOTLIB = $(subst lib,,$(LIBS_A_NOTDIR)) # 去掉文件名的lib,留下部分为xxx.a LIBS_A_OBJS = $(patsubst %.a,-l%, $(LIBS_A_NOTLIB)) # 去掉文件名的后缀并在前面添加-l,留下部分为-lxxx # 获取动态库名字 LIBS_SO = $(wildcard $(PROJECT_ROOT_PATH)/lib/*.so) # 获取该目录下动态库(*.so)的路径名 LIBS_SO_NOTDIR = $(notdir $(LIBS_SO)) # 去掉路路径,只留下文件名为libxxx.so LIBS_SO_NOTLIB = $(subst lib,,$(LIBS_SO_NOTDIR)) # 去掉文件名的lib,留下部分为xxx.so LIB_SO_OBJS = $(patsubst %.so,-l%, $(LIBS_SO_NOTLIB)) # 去掉文件名的后缀并在前面添加-l,留下部分为-lxxx #links $(EXE_NAME): $(CCOBJS) $(CC) $^ -o $@ $(LDFLAGS) $(LIB_NAMES) #compile $(CCOBJS): %.o: %.c $(CC) $(INCPATH) $(CFLAGS) -c $


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有